package com.wq.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wq.BusinessException;
import com.wq.context.BaseContext;
import com.wq.dto.ApplicationDTO;
import com.wq.dto.ApprovalDTO;
import com.wq.entity.Application;
import com.wq.entity.Department;
import com.wq.entity.Type;
import com.wq.enums.RespEnum;
import com.wq.mapper.ApplicationMapper;
import com.wq.mapper.DepartmentMapper;
import com.wq.service.ApplicationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wq.service.TypeService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wq
 * @since 2025-11-09
 */
@Service
public class ApplicationServiceImpl extends ServiceImpl<ApplicationMapper, Application> implements ApplicationService {

    @Resource
    private TypeService typeService;

    @Resource
    private DepartmentMapper departmentMapper;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public Application submitApplication(ApplicationDTO applicationDTO) {
        // 获取当前登录用户ID
        Long currentUserId = BaseContext.getCurrentId();
        if (currentUserId == null) {
            throw new BusinessException(RespEnum.TOKEN_ERROR);
        }

        // 调用用户服务获取用户信息
        Map<String, Object> userInfo = getUserInfo(currentUserId);
        if (userInfo == null) {
            throw new BusinessException(RespEnum.INVALID_ACCOUNT);
        }

        // 获取请假类型信息
        Type leaveType = typeService.getById(applicationDTO.getLeaveTypeId());
        if (leaveType == null || !leaveType.getStatus()) {
            throw new BusinessException( "请假类型不存在或已禁用");
        }

        // 创建请假申请
        Application application = new Application();
        BeanUtils.copyProperties(applicationDTO, application);

        // 生成申请编号
        String applicationNo = generateApplicationNo();
        application.setApplicationNo(applicationNo);

        // 设置用户信息
        application.setUserId(currentUserId.intValue());
        application.setUserName((String) userInfo.get("realName"));
        application.setDeptId((Integer) userInfo.get("deptId"));
        
        // 直接查询部门表获取部门名称
        Department department = departmentMapper.selectById(application.getDeptId());
        if (department != null) {
            application.setDeptName(department.getDeptName());
        } else {
            // 如果部门不存在，设置默认值
            application.setDeptName("未知部门");
        }

        // 设置请假类型信息
        application.setLeaveTypeName(leaveType.getTypeName());

        // 设置状态为待审批
        application.setStatus(0);  // 0-待审批

        // 保存
        this.save(application);

        return application;
    }

    @Override
    public Page<Application> getMyApplications(Integer pageNum, Integer pageSize) {
        Long currentUserId = BaseContext.getCurrentId();
        if (currentUserId == null) {
            throw new BusinessException(RespEnum.TOKEN_ERROR);
        }

        Page<Application> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Application> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Application::getUserId, currentUserId.intValue())
                .orderByDesc(Application::getCreateTime);

        return this.page(page, wrapper);
    }

    @Override
    public Page<Application> getPendingApprovals(Integer pageNum, Integer pageSize) {
        Long currentUserId = BaseContext.getCurrentId();
        if (currentUserId == null) {
            throw new BusinessException(RespEnum.TOKEN_ERROR);
        }

        // 获取当前用户信息
        Map<String, Object> userInfo = getUserInfo(currentUserId);
        if (userInfo == null) {
            throw new BusinessException(RespEnum.INVALID_ACCOUNT);
        }

        Integer roleType = (Integer) userInfo.get("roleType");
        Integer deptId = (Integer) userInfo.get("deptId");

        // 只有部门经理和系统管理员可以审批
        if (roleType == null || roleType < 2) {
            throw new BusinessException( "无审批权限");
        }

        Page<Application> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Application> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Application::getStatus, 0);  // 0-待审批

        // 部门经理只能查看本部门的申请
        if (roleType == 2) {
            wrapper.eq(Application::getDeptId, deptId);
        }
        // 系统管理员可以查看所有部门

        wrapper.orderByAsc(Application::getCreateTime);

        return this.page(page, wrapper);
    }

    @Override
    public Boolean approveApplication(ApprovalDTO approvalDTO) {
        Long currentUserId = BaseContext.getCurrentId();
        if (currentUserId == null) {
            throw new BusinessException(RespEnum.TOKEN_ERROR);
        }

        // 获取当前用户信息
        Map<String, Object> userInfo = getUserInfo(currentUserId);
        if (userInfo == null) {
            throw new BusinessException(RespEnum.INVALID_ACCOUNT);
        }

        Integer roleType = (Integer) userInfo.get("roleType");
        Integer deptId = (Integer) userInfo.get("deptId");

        // 检查权限
        if (roleType == null || roleType < 2) {
            throw new BusinessException( "无审批权限");
        }

        // 获取申请信息
        Application application = this.getById(approvalDTO.getApplicationId());
        if (application == null) {
            throw new BusinessException("申请不存在");
        }

        // 检查申请状态
        if (application.getStatus() != 0) {
            throw new BusinessException(RespEnum.ERROR_STATUS);
        }

        // 部门经理只能审批本部门的申请
        if (roleType == 2 && !application.getDeptId().equals(deptId)) {
            throw new BusinessException("只能审批本部门的请假申请");
        }

        // 更新审批信息
        application.setStatus(approvalDTO.getStatus());  // 1-已通过，2-已拒绝
        application.setApproverId(currentUserId.intValue());
        application.setApproverName((String) userInfo.get("realName"));
        application.setApprovalOpinion(approvalDTO.getApprovalOpinion());
        application.setApprovalTime(new Date());

        return this.updateById(application);
    }

    @Override
    public Boolean cancelApplication(Integer applicationId) {
        Long currentUserId = BaseContext.getCurrentId();
        if (currentUserId == null) {
            throw new BusinessException(RespEnum.TOKEN_ERROR);
        }

        Application application = this.getById(applicationId);
        if (application == null) {
            throw new BusinessException( "申请不存在");
        }

        // 只能取消自己的申请
        if (!application.getUserId().equals(currentUserId.intValue())) {
            throw new BusinessException( "只能取消自己的申请");
        }

        // 只能取消待审批的申请
        if (application.getStatus() != 0) {
            throw new BusinessException(RespEnum.ERROR_STATUS);
        }

        // 设置状态为已取消
        application.setStatus(3);  // 3-已取消
        return this.updateById(application);
    }

    @Override
    public Page<Application> getAllApplications(Integer pageNum, Integer pageSize) {
        Long currentUserId = BaseContext.getCurrentId();
        if (currentUserId == null) {
            throw new BusinessException(RespEnum.TOKEN_ERROR);
        }

        // 获取当前用户信息
        Map<String, Object> userInfo = getUserInfo(currentUserId);
        if (userInfo == null) {
            throw new BusinessException(RespEnum.INVALID_ACCOUNT);
        }

        Integer roleType = (Integer) userInfo.get("roleType");

        // 只有系统管理员可以查看所有申请
        if (roleType == null || roleType != 3) {
            throw new BusinessException("无权限查看所有申请");
        }

        Page<Application> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Application> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Application::getCreateTime);

        return this.page(page, wrapper);
    }

    @Override
    public Page<Application> getApprovalHistory(Integer pageNum, Integer pageSize) {
        Long currentUserId = BaseContext.getCurrentId();
        if (currentUserId == null) {
            throw new BusinessException(RespEnum.TOKEN_ERROR);
        }

        // 获取当前用户信息
        Map<String, Object> userInfo = getUserInfo(currentUserId);
        if (userInfo == null) {
            throw new BusinessException(RespEnum.INVALID_ACCOUNT);
        }

        Integer roleType = (Integer) userInfo.get("roleType");
        Integer deptId = (Integer) userInfo.get("deptId");

        // 只有部门经理和系统管理员可以查看审批历史
        if (roleType == null || roleType < 2) {
            throw new BusinessException("无权限查看审批历史");
        }

        Page<Application> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Application> wrapper = new LambdaQueryWrapper<>();
        
        // 查询已审批的记录（状态为1-已通过或2-已拒绝）
        wrapper.in(Application::getStatus, 1, 2);
        
        // 部门经理只能查看本部门的审批历史
        if (roleType == 2) {
            wrapper.eq(Application::getDeptId, deptId);
        }
        // 系统管理员可以查看所有部门

        wrapper.orderByDesc(Application::getApprovalTime);

        return this.page(page, wrapper);
    }

    /**
     * 生成申请编号
     */
    private String generateApplicationNo() {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        return "LA" + now.format(formatter) + String.format("%04d", (int)(Math.random() * 10000));
    }

    /**
     * 调用用户服务获取用户信息
     */
    private Map<String, Object> getUserInfo(Long userId) {
        try {
            List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
            if (instances == null || instances.isEmpty()) {
                return null;
            }
            String url = instances.get(0).getUri() + "/user/" + userId;
            Map response = restTemplate.getForObject(url, Map.class);
            if (response != null && response.get("code").equals(200)) {
                return (Map<String, Object>) response.get("data");
            }
        } catch (Exception e) {
            log.error("获取用户信息失败", e);
        }
        return null;
    }
}
